package com.woniuxy.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.nimbusds.jose.JOSEException;
import com.woniuxy.entity.Address;
import com.woniuxy.entity.Book;
import com.woniuxy.entity.ShoppingCart;
import com.woniuxy.entity.User;
import com.woniuxy.entity.dto.LoginDTO;
import com.woniuxy.entity.dto.UserDTO;
import com.woniuxy.mapper.UserMapper;
import com.woniuxy.service.UserService;
import com.woniuxy.util.JWTUtil;
import com.woniuxy.util.UserConenxt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author dingpf
 * @version 1.0
 * @description
 * @create 2025/4/22 15:42
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    //专门操作reids工具类（新增，删除，查看）
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RedisTemplate redisTemplateInit;

    /**
     * 用户登录接口
     * 1：根据用户名查询用户信息
     * 2：对比数据库的密码和前端输入密码
     * 3：给该用户生成jwt
     * 4: 把jwt存入redis中
     *
     * @param user
     * @return
     */
    @Override
    public LoginDTO Login(User user) throws JOSEException {
        //1：根据用户名查询用户信息
        User userInfo = userMapper.queryUserByAccount(user.getAccount());
        if (userInfo == null){
            return null;
        }
        //2: 对比数据库的密码和前端输入密码
        //为了密码的安全性，不会直接用原生的密码加密后放入数据库。给（密码加上+盐值）后在放入数据库
        String md5PWD = SecureUtil.md5(user.getPassword()+"1a2b3c4d");
        if (!userInfo.getPassword().equals(md5PWD)){
            return null;
        }
        //3: 给该用户生成jwt
        HashMap<String, Object> userMap = new HashMap<>();
        userMap.put("id",userInfo.getId());
        userMap.put("account",userInfo.getAccount());
        String jwt = JWTUtil.createJWT(userMap);

        //4: 把jwt存入redis中 redis:采用key-val方式存储的数据库。 mysql：表格
        //参数3：数值，参数4：时间单位（秒，毫秒，分钟）
        stringRedisTemplate.opsForValue().set("JWT:"+userInfo.getId(),jwt, 15, TimeUnit.DAYS);

        return new LoginDTO(jwt,new UserDTO(userInfo));//PO改成DTO
    }

    /**
     * 用户添加购物车
     * 1：判断该用户是否添加过此书籍
     *    没有添加过：新增
     *    添加过了：修改
     * @param id
     * @param buyNum
     */
    @Override
    public void addCart(Integer id, Integer buyNum) throws ParseException {
        //怎么获取用户id?
        Integer userId = UserConenxt.getUserId();
        ShoppingCart shoppingCart = userMapper.queryUserShoppingCart(userId, id);

        ShoppingCart shoppingCartInfo = new ShoppingCart();
        shoppingCartInfo.setBookId(id);
        //考虑新增，还是修改
        shoppingCartInfo.setBuyNum(shoppingCart == null ? buyNum : buyNum + shoppingCart.getBuyNum());

        //获取redis缓存的该书籍信息（获取最新单价）
        Book cacheBook = (Book)redisTemplateInit.opsForHash().get("BOOKSERVICEIMPL:QUERYBYID", id + "");
        shoppingCartInfo.setBuyPrice(cacheBook.getPrice()); //最新单价
        shoppingCartInfo.setUserId(userId);
        shoppingCartInfo.setTotalPrice(cacheBook.getPrice().multiply(new BigDecimal(shoppingCartInfo.getBuyNum())));

        if (shoppingCart == null){
            //新增 shoppingCartInfo
            userMapper.addShoppingCart(shoppingCartInfo);
        } else {
            //修改 shoppingCartInfo
            shoppingCartInfo.setId(shoppingCart.getId());
            userMapper.updateShoppingCart(shoppingCartInfo);

        }

    }

    /**
     * 查询地址和购物车信息
     * @return
     */
    @Override
    public Map queryAddrAndUserCart() throws ParseException {
        Integer userId = UserConenxt.getUserId();
        List<Address> addresses = userMapper.queryUserAddr(userId);
        List<ShoppingCart> shoppingCarts = userMapper.queryUserShopingCart(userId);
        Map map = new HashMap();
        map.put("addresses",addresses);
        map.put("shoppingCarts",shoppingCarts);
        return map;
    }
}
